package com.cn.system.sync;

import com.cn.system.crawler.XxlCrawler;
import com.cn.system.crawler.parser.PageParser;
import com.cn.system.entity.*;
import com.cn.system.mapper.TCardsMapper;
import com.cn.system.mapper.TGroupCourseMapper;
import com.cn.system.service.BaseService;
import com.cn.system.utils.CommonsUtils;
import com.cn.system.utils.TimeUtils;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SyncToDatabases {

  @Resource(name="tGroupCourseServiceImpl")
  private BaseService<TGroupCourse> baseService;

  @Resource(name="tCardsServiceImpl")
  private BaseService<TCards> tCardsBaseService;

  @Scheduled(cron = "0 0 * * * ?")
  public void sync() {
    XxlCrawler crawler = new XxlCrawler.Builder()
        .setUrls("https://fudao.qq.com/grade/7003/")
        .setWhiteUrlRegexs("^https://fudao.qq.com/grade/*[1-9]\\d*/$")
        .setThreadCount(3)
        .setPageParser(new PageParser<CrawlerModel>() {
          @Override
          public void parse(Document html, Element pageVoElement, CrawlerModel pageVo) {
            // 解析封装 PageVo 对象
            String pageUrl = html.baseUri();
//            System.out.println(pageUrl + "：" + pageVo.toString());
            doDataToDataBasesProcess(pageUrl, pageVo);
          }
        })
        .build();
    crawler.start(true);
  }

  /**
   *
   * @param pageUrl current request url
   * @param pageVo  entity include group and card
   */
  public void doDataToDataBasesProcess(String pageUrl, CrawlerModel pageVo) {
    if (pageVo!= null && pageUrl != null) {
      // process group
      String courseNumber = pageUrl.substring(pageUrl.length() - 5, pageUrl.length()-1);
      doProcessGroup(courseNumber,pageVo.getGroupNode());
      // process card and class
      doProcessCard(courseNumber, pageVo.getCards());

    }
  }

  /**
   * group information
   * @param courseNumber class number
   * @param groupNode gain of node information
   */
  public void doProcessGroup(String courseNumber, List<GroupNode> groupNode){
    if (groupNode!=null) {
      groupNode.stream().map(t -> {
        if (t.getContentDesc()!=null || t.getContentHint()!=null || t.getTitle()!=null) {
          //TODO 这个需要考虑对数据库的性能影响，如果在数据在数据库中插入过，无需再次插入，最好把插入数据存入缓存中，减少数据库的压力.
          //TODO 需要注意的问题就是双写的问题
          TGroupCourse tGroupCourse = new TGroupCourse();
          tGroupCourse.setContentDesc(t.getContentDesc());
          tGroupCourse.setContentHint(t.getContentHint());
          tGroupCourse.setCourseNum(courseNumber);
          tGroupCourse.setTitle(t.getTitle());
          tGroupCourse.setInsertTime(TimeUtils.toDateToString(new Date()));
          List<TGroupCourse> list = baseService.list(tGroupCourse);
          if (list!=null && list.size() == 0) {
            tGroupCourse.setUpdateTime(TimeUtils.toDateToString(new Date()));
            tGroupCourse.setId(CommonsUtils.getUUID());
            baseService.add(tGroupCourse);
            return null;
          }else {
            System.out.println("====>>>> 已经插入过" + courseNumber);
          }
        }
        return null;
      }).collect(Collectors.toList());
    }
  }

  /**
   * @param courseNumber
   * @param cards
   */
  public void doProcessCard(String courseNumber, List<CourseCard> cards) {
    if (cards!=null) {
      cards.stream().map(t -> {
        if (t.getTeachInfo()!=null || t.getTitle()!=null || t.getCourseHint()!=null) {
          //TODO 这个需要考虑对数据库的性能影响，如果在数据在数据库中插入过，无需再次插入，最好把插入数据存入缓存中，减少数据库的压力.
          //TODO 需要注意的问题就是双写的问题
          TCards tCards = new TCards();
          tCards.setCourseHit(t.getCourseHint());
          tCards.setTeachInfo(t.getTeachInfo());
          tCards.setCoursePrice(t.getCoursePrice());
          tCards.setTitle(t.getTitle());
          tCards.setCourseNum(courseNumber);
          tCards.setInsertTime(TimeUtils.toDateToString(new Date()));
          tCards.setCourseTime(t.getCourseTime());
          List<TCards> list = tCardsBaseService.list(tCards);
          if (list!=null && list.size() == 0) {
            tCards.setUpdateTime(TimeUtils.toDateToString(new Date()));
            tCards.setId(CommonsUtils.getUUID());
            tCardsBaseService.add(tCards);
            return null;
          }else {
            System.out.println("====>>>> 已经插入过" + courseNumber);
          }
        }
        return null;
      }).collect(Collectors.toList());
    }
  }

}
